#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
#include "stack.h"

void stackNew(stack *s,int elemSize, void (*freeFn)(void *)){
	s->elemSize = elemSize;
	s->logLength = 0;
	s->allocLength = 4;
	s->freeFn = freeFn;
	s->elems = malloc(s->allocLength*s->elemSize);
	assert(s->elems!=NULL);
}

void stackDispose(stack *s){
	if(s->freeFn!=NULL){
		for(int i=0;i<s->logLength;i++){
			s->freeFn((char*)s->elems+i*s->elemSize);
		}
	}
	free(s->elems);
}
static void stackGrow(stack *s){
	s->elems = realloc(s->elems,s->allocLength*2*s->elemSize);
	s->allocLength *= 2;
}

void stackPush(stack *s, void *elemAddr){
	if(s->logLength == s->allocLength)
		stackGrow(s);
	void *elems = (char*)s->elems+s->logLength*s->elemSize;
	memcpy(elems,elemAddr,s->elemSize);
	s->logLength++;
}

void stackPop(stack *s,void *elemAddr){
	void *elems = (char*)s->elems+s->elemSize*(s->logLength-1);
	memcpy(elemAddr,elems,s->elemSize);
	s->logLength--;
}
